import { call } from 'naive-ui/es/_utils';
import Net from './net.js'
export class NodeHandler {
    
    constructor(name, type){
        this.name = name;
        this.type = type;
        this.usepost = false
        this.use_stream = true
        this.cookie = ""
        this.headers = {}
        this.api = ""
        this.server = ""
        this.args = []
        this.requstArgs = {}
        this.outputArgs = []
        this.data = {}
    }

    update(data){
        // for each kv update to this.data
        if (typeof data == "object"){
            for (let key in data){
                this.data[key] = data[key]
            }
        }else{
            alert("data must be an dict object")
        }
        
    }

    ai_config_preview(after){
        fetch(`${this.server}/get_preview`,{
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify(this.data)
        }).then((response) => {
            return response.json()
        }).then((data) => {   
            after(data)
        })
    }

    save(after){
        let postData = {
            type: this.type,
            name: this.name,
        }
        if (this.api != ""){
            postData["api"] = this.api;
        }
        if (this.args.length > 0){
            postData["args"] = this.args;
        }
        if (this.outputArgs != null && this.outputArgs.length > 0){
            postData["outputArgs"] = this.outputArgs;
        }

        for (let key in this.data){
            postData[key] = this.data[key]
        }
        postData["headers"] = this.headers
        postData["cookie"] = this.cookie
        postData["stream"]  = this.use_stream
        postData["usepost"] = this.usepost

        fetch(`${this.server}/save_agent`,{
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(postData)
        }).then((response) => {
            
            if (after != null){
                after(response)
            }
        })
    }
    
    del(after){
        let self = this;
        console.log("del node:", self.name)
        fetch(`${this.server}/del_agent`,{
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify({
              "name": self.name
            })
        }).then(res => res.json()).then((data) => {
            
            if (after != null){
                after(data)
            }
        })
    }

    load(after){
        let self = this;
        console.log("load node:", self.name)
        fetch(`${this.server}/load_agent`,{
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify({
              "name": self.name
            })
        }).then(res => res.json()).then((data) => {
            for(let key in data){
                self.data[key] = data[key]
            }
            if (after != null){
                after(self.data)
            }
            
        })
    }

    from_net_template(nettemplate){
        this.update({
            data:nettemplate.value.data
        })
        this.usepost = nettemplate.value.usepost
        this.use_stream = nettemplate.value.stream
        this.headers = nettemplate.value.headers
        this.cookie = nettemplate.value.cookie

        this.name = nettemplate.value.name
        this.type = nettemplate.value.type
        this.api = nettemplate.value.api
        this.args = nettemplate.value.inputArgs
        this.outputArgs = nettemplate.value.outputArgs
        return this
    }

    stream(kwargs, callback, end_callback, err_callback){
        let self = this;
        if (this.api == null || this.api == ""){
            if (err_callback != null){
                err_callback("net.api is null")
            }else{
                alert("net.api is null")
            }
        }

        if (this.data == null || this.data.data == null){
            if (err_callback != null){
                err_callback("net.data.data is null")
            }else{
                alert("net.data is null")
            }
        }

        try{
            let requetQuery = JSON.stringify(this.data.data)
            if (kwargs != null){
                for(let name in kwargs){
                    let val = kwargs[name]
                    console.log("patch:",`$\{${name}\}`, val)
                    requetQuery = requetQuery.replaceAll(`$\{${name}\}`, val)
                }
            }
            let reqData = JSON.parse(requetQuery)
            let net = new Net(this.type, this.api, reqData)
            net.options = {
                headers: self.headers,
                use_stream: self.use_stream,
                usepost: self.usepost,
                cookie: self.cookie,
            }
            net.connect((chunk)=>{
                if (self.outputArgs != null && self.outputArgs.length > 0){
                    for(let name of self.outputArgs){
                        chunk = chunk[name]
                    }
                }
                if (Array.isArray(chunk)){
                    callback(chunk)
                }else{
                    callback([chunk])
                }
                
            }, ()=>{
                if (end_callback != null){
                    end_callback()
                }
                
            })
        } catch (error) {
            // console.error('Error in postAndReceiveSSE:', error);
            
            if (err_callback != null){
                err_callback(error)
            } else{
                alert(`网络请求失败:${error}`)
            }
            
        }
  
  
    }

    static List(after, test_server){
        if (test_server == null){
            test_server = ""
        }
        fetch(`${test_server}/list_agent`,{
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            }
        }).then(res => res.json()).then((data) => {
            let d = data;
            let list_agent = [];
            for(let i of d){
                list_agent.push(i)
            }
            if (after != null){
                after(list_agent)
            }
        })
    }
}